<?php

App::uses('AppModel', 'Model');
App::uses('CompositeKeyModel', 'Model');

/**
 * OrganisationMemberGroup Model
 *
 * @property Member $Member
 * @property OrganisationGroup $OrganisationGroup
 */
class OrganisationMember extends CompositeKeyModel {

    //The Associations below have been created with all possible keys, those that are not needed can be removed

    public $useDbConfig = "organisations";
    public $primaryKeys = array('id', 'organisation_id');

    /**
     * belongsTo associations
     *
     * @var array
     */
    public $belongsTo = array(
        'Organisation' => array(
            'className' => 'Organisation',
            'foreignKey' => 'organisation_id',
            'conditions' => '',
            'fields' => '',
            'order' => '',
            'counterCache' => true,
            'counterScope' => array(
                'OrganisationMember.active' => 1,
                'OrganisationMember.approved' => 1
            )
        ),
        'OrganisationMemberCategory' => array(
            'className' => 'OrganisationMemberCategory',
            'foreignKey' => 'organisation_member_category_id',
            'conditions' => '',
            'fields' => '',
            'order' => '',
            'counterCache' => true,
            'counterScope' => array(
                'OrganisationMember.active' => 1,
                'OrganisationMember.approved' => 1
            )
        ),
        'Member' => array(
            'className' => 'Member',
            'foreignKey' => 'member_id',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        ),
        'Approver' => array(
            'className' => 'OrganisationAccount',
            'foreignKey' => 'approved_by',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        )
    );
    
    public $hasOne = array(
        'OrganisationMemberNote' => array(
            'className' => 'OrganisationMemberNote',
            'foreignKey' => 'organisation_member_id',
            'dependent' => false,
            'conditions' => '',
            'fields' => '',
            'order' => '',
            'limit' => '',
            'offset' => '',
            'exclusive' => '',
            'finderQuery' => '',
            'counterQuery' => ''
        ),
        'OrganisationMemberImage' => array(
            'className' => 'OrganisationMemberImage',
            'foreignKey' => 'organisation_member_id',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        )
    );
    
    public $hasMany = array(
        'ModuleMemberContribution' => array(
            'className' => 'ModuleMemberContribution',
            'foreignKey' => 'organisation_member_id',
            'dependent' => false,
            'conditions' => '',
            'fields' => '',
            'order' => '',
            'limit' => '',
            'offset' => '',
            'exclusive' => '',
            'finderQuery' => '',
            'counterQuery' => ''
        ),
        'OrganisationMemberAnniversary' => array(
            'className' => 'OrganisationMemberAnniversary',
            'foreignKey' => 'organisation_member_id',
            'dependent' => false,
            'conditions' => '',
            'fields' => '',
            'order' => '',
            'limit' => '',
            'offset' => '',
            'exclusive' => '',
            'finderQuery' => '',
            'counterQuery' => ''
        ),
        'OrganisationMemberGroup' => array(
            'className' => 'OrganisationMemberGroup',
            'foreignKey' => 'organisation_member_id',
            'dependent' => false,
            'conditions' => '',
            'fields' => '',
            'order' => '',
            'limit' => '',
            'offset' => '',
            'exclusive' => '',
            'finderQuery' => '',
            'counterQuery' => ''
        ),
        'OrganisationGroupLeader' => array(
            'className' => 'OrganisationGroupLeader',
            'foreignKey' => 'organisation_member_id',
            'dependent' => false,
            'conditions' => '',
            'fields' => '',
            'order' => '',
            'limit' => '',
            'offset' => '',
            'exclusive' => '',
            'finderQuery' => '',
            'counterQuery' => ''
        )
    );
    
    public function afterSave($created, $options = array()) {
        parent::afterSave($created, $options);
        
        if( $created ) {
            if( isset($this->data['OrganisationMember']['organisation_member_category_id']) ) {
                $this->OrganisationMemberCategory->incrementID($this->data['OrganisationMember']['organisation_member_category_id']);
            }
        }
    }
    
    public function createDefaultMember($organisation_id, $member_account_id, $settings) {
        
        $member_account = ClassRegistry::init('MemberAccount')->find('first', array(
            'contain' => array('Member'),
            'conditions' => array(
                'MemberAccount.id' => $member_account_id
            )
        ));
        
        if( !$member_account ) {
            return array('status' => 'failed', 'message' => 'Invalid member account information supplied');
        }
        
        $orgMemberData = array(
            'OrganisationMember' => array(
                'organisation_id' => $organisation_id,
                'member_id' => $member_account['Member']['id'],
                'organisation_member_category_id' => $settings['default_category']['id'],
            )
        );

        $this->saveAll($orgMemberData);
        
        // get the organisation member id
        $org_mem_id = $this->id;
        
        $this->approve($organisation_id, $member_account['Member']['id'], $settings['default_account_id']);
        
        return array('organisation_member_id' => $org_mem_id, 'organisation_account_id' => $settings['default_account_id']);
    }
    
    public function createMember($organisation_id, $category_id, $params) {
         
         $memberData = array(
             'Member' => array(
                 'title' => $params['title'],
                 'first_name' => $params['first_name'],
                 'last_name' => $params['last_name'],
                 'dob' => $params['dob'],
                 'gender' => $params['gender'],
                 'marital_status' => $params['marital_status'],
                 'email' => $params['email'],
                 'mobile_number' => $params['mobile_number'],
                 'office_number' => $params['office_number'],
                 'postal_address' => $params['postal_address'],
                 'source_organisation_id' => $organisation_id
             )
        );
         
        $member = $this->Member->save($memberData);
        
        if( !$member ) {
            return array('status' => 'failed', 'message' => 'Profile creation failed. Please contact support');
        }
         
        $orgMemberData = array(
            'OrganisationMember' => array(
                'organisation_id' => $organisation_id,
                'organisation_member_category_id' => $category_id,
                'member_id' => $this->Member->id,
                'source' => isset($params['source']) ? $params['source'] : 'public',
                'approved' => 0,
                'active' => 1
            )
        );
        
        $orgMember = $this->save($orgMemberData);
        
        if( $orgMember ) {
            $category = $this->OrganisationMemberCategory->getCategory($organisation_id, $category_id);
            $member_name = $params['first_name'] . " " . $params['last_name']; 
            $category_name = $category['category']['name'];

            ClassRegistry::init('OrganisationNotification')->add($organisation_id, 'member_registration', array(
                'source_id' => $this->Member->id,
                'target_id' => $category_id,
                'category_name' => $category_name,
                'member_name' => $member_name
            ));
        }
        
        return array('member' => $member, 'org_member' => $orgMember);
    }
    
    /**
     * Returns the organisation - member association record
     * 
     * @param int $organisation_id
     * @param int $member_id
     * @return type
     */
    public function getAssociation($organisation_id, $member_id, $allData = true) {
        $contains = array(
            'Member' => array(
                'MemberSpouse' => array('conditions' => array('active' => 1)),
                'MemberParent' => array('conditions' => array('active' => 1)),
                'MemberChild' => array('conditions' => array('active' => 1)),
                'MemberPhoneNumber' => array('conditions' => array('active' => 1)),
                'MemberEmail' => array('conditions' => array('active' => 1))
            ), 
            'OrganisationMemberImage' => array(
                'MemberImage',
                'conditions' => array('OrganisationMemberImage.member_image_id IS NOT' => null),
                'order' => array('OrganisationMemberImage.id' => 'desc')
            ),
            'OrganisationMemberAnniversary' => array(
                'conditions' => array('organisation_id' => $organisation_id, 'active' => 1)
            ), 
            'OrganisationMemberGroup' => array(
                'conditions' => array('organisation_id' => $organisation_id, 'active' => 1),
                'OrganisationGroup' => array(
                    'conditions' => array('organisation_id' => $organisation_id, 'active' => 1)
                )
            ),
            'OrganisationMemberNote' => array(
                'conditions' => array('OrganisationMemberNote.organisation_id' => $organisation_id)
            )
        );
        
        return $this->find('first', array(
            'contain' => $allData ? $contains : array(),
            'conditions' => array(
                'OrganisationMember.organisation_id' => $organisation_id,
                'OrganisationMember.member_id' => $member_id
            )
        ));
    }
    
    /**
     * 
     * @param type $organisation_id
     * @param type $member_id
     * @return type
     */
    public function createPublicAssociation($organisation_id, $member_id) {
        $this->create();
        
        return $this->save(array(
            'organisation_id' => $organisation_id,
            'member_id' => $member_id,
            'status' => 'member',
            'approved' => 0,
            'source' => 'public',
            'active' => 1
        ));
    }
    
    /**
     * Returns the total number of members in a particular status group
     * 
     * @param int $organisation_id
     * @param string $status defaults to 'member'
     * @return int
     */
    public function getTotalMembers($organisation_id) {
        $data = $this->Organisation->find('first', array(
            'conditions' => array('Organisation.id' => $organisation_id),
            'recursive' => -1
        ));
        
        return $data['Organisation']['organisation_member_count'];
    }
    
    /**
     * Returns the number of members by gender of a particular status group
     * 
     * @param int $organisation_id
     * @param string $gender
     * @param string $status defaults to 'member'
     * 
     * @return int
     */
    public function getTotalMembersByGender($organisation_id, $gender, $status = 'member') {
        $member_count = $this->find('count', array(
            'conditions' => array(
                'Member.gender' => $gender,
                'OrganisationMember.organisation_id' => $organisation_id,
                'OrganisationMember.status' => $status,
                'OrganisationMember.active' => 1,
                'OrganisationMember.approved' => 1
            )
        ));
        
        return $member_count;
    }
    
    /**
     * Returns the number of members by gender of a particular status group
     * 
     * @param int $organisation_id
     * 
     * @return int
     */
    public function genderStats($organisation_id) {
        
        $data = $this->find('all', array(
            'fields' => array('Member.gender', 'COUNT(Member.id) AS cnt'),
            'conditions' => array(
                'LOWER(Member.gender)' => array('male', 'female'),
                'OrganisationMember.organisation_id' => $organisation_id,
                'OrganisationMember.active' => 1,
                'OrganisationMember.approved' => 1
            ),
            'group' => array('LOWER(Member.gender)')
        ));
        
        $stats = array('Gender' => array());
        
        foreach($data as $rec) {
            $gender = ucfirst( $rec['Member']['gender'] );
            $cnt = $rec[0]['cnt'];
            
            $stats['Gender'][$gender] = $cnt;
        }
        
        return $stats;
    }
    
    /**
     * Returns the number of members by gender of a particular status group
     * 
     * @param int $organisation_id
     * 
     * @return int
     */
    public function maritalStatusStats($organisation_id) {
        
        $data = $this->find('all', array(
            'fields' => array('Member.marital_status', 'COUNT(Member.id) AS cnt'),
            'conditions' => array(
                'NOT' => array(
                    'Member.marital_status' => null,
                    'Member.marital_status' => ''
                ),
                'OrganisationMember.organisation_id' => $organisation_id,
                'OrganisationMember.active' => 1,
                'OrganisationMember.approved' => 1
            ),
            'group' => array('Member.marital_status')
        ));
        
        $stats = array('Marital Status' => array());
        
        foreach($data as $rec) {
            $status = ucfirst( $rec['Member']['marital_status'] );
            $cnt = $rec[0]['cnt'];
            
            $stats['Marital Status'][$status] = $cnt;
        }
        
        return $stats;
    }
    
    /**
     * Returns the employment status stats for members in the specified organisation
     * 
     * @param int $organisation_id
     * 
     * @return int
     */
    public function employmentStats($organisation_id) {
        
        $data = $this->find('all', array(
            'fields' => array('Member.employment_status', 'COUNT(Member.id) AS cnt'),
            'conditions' => array(
                'NOT' => array(
                    'Member.employment_status' => null,
                    'Member.employment_status' => ''
                ),
                'OrganisationMember.organisation_id' => $organisation_id,
                'OrganisationMember.active' => 1,
                'OrganisationMember.approved' => 1
            ),
            'group' => array('LOWER(Member.employment_status)')
        ));
        
        $stats = array('Employment Status' => array());
        
        foreach($data as $rec) {
            $status = ucfirst( $rec['Member']['employment_status'] );
            $cnt = $rec[0]['cnt'];
            
            $stats['Employment Status'][$status] = $cnt;
        }
        
        return $stats;
    }
    
    public function dayOfBirthStats($organisation_id) {
        $data = $this->find('all', array(
            'fields' => array('DAYNAME(Member.dob) AS dayname', 'COUNT(Member.id) AS cnt'),
            'conditions' => array(
                'NOT' => array(
                    'Member.dob' => null,
                    'Member.dob' => '0000-00-00'
                ),
                'OrganisationMember.organisation_id' => $organisation_id,
                'OrganisationMember.active' => 1,
                'OrganisationMember.approved' => 1
            ),
            'group' => array('DAYNAME(Member.dob)'),
            'order' => array('DAYOFWEEK(Member.dob)')
        ));
        
        $stats = array('Day Of Birth' => array());
        
        foreach($data as $rec) {
            $gender = ucfirst( $rec[0]['dayname'] );
            $cnt = $rec[0]['cnt'];
            
            $stats['Day Of Birth'][$gender] = $cnt;
        }
        
        return $stats;
    }
    
    public function monthOfBirthStats($organisation_id) {
        $data = $this->find('all', array(
            'fields' => array('MONTHNAME(Member.dob) AS dayname', 'COUNT(Member.id) AS cnt'),
            'conditions' => array(
                'NOT' => array(
                    'Member.dob' => null,
                    'Member.dob' => '0000-00-00'
                ),
                'OrganisationMember.organisation_id' => $organisation_id,
                'OrganisationMember.active' => 1,
                'OrganisationMember.approved' => 1
            ),
            'group' => array('MONTHNAME(Member.dob)'),
            'order' => array('MONTH(Member.dob)')
        ));
        
        $stats = array('Month Of Birth' => array());
        
        foreach($data as $rec) {
            $gender = ucfirst( $rec[0]['dayname'] );
            $cnt = $rec[0]['cnt'];
            
            $stats['Month Of Birth'][$gender] = $cnt;
        }
        
        return $stats;
    }
    
    /**
     * Returns the total number of members in a specific category for an organisation
     * 
     * @param int $organisation_id
     * @param int $category_id
     * @return mixed
     */
    public function getTotalMembersByCategory($organisation_id, $category_id) {
        if( $category_id == -1 ) {
            return $this->getTotalMembers($organisation_id);
        }
        
        $sql = sprintf("SELECT COUNT(id) as cnt FROM organisation_members OrganisationMember "
                . "WHERE OrganisationMember.organisation_id = %d AND OrganisationMember.organisation_member_category_id = %d "
                . "OrganisationMember.active = 1 AND OrganisationMember.approved = 1", $organisation_id, $category_id);
        
        $result = $this->query($sql);
        
        return $result[0][0]['cnt'];
    }
    
    /**
     * 
     * @param int $organisation_id the organisation whose records should be returned
     * @param int $offset start offset for records to return
     * @param int $limit number of records to return
     * @param mixed $sort_order - recent, alpha
     * @param mixed $status - member, visitor, deceased
     * @return type
     */
    public function getMembersForList($organisation_id, $offset = 0, $limit = 40, $sort_order = 'recent', $status = 'member') {
        $result = $this->find('all', array(
            'contain' => array('Member'),
            'conditions' => array(
                'OrganisationMember.organisation_id' => $organisation_id,
                'OrganisationMember.active' => 1,
                'OrganisationMember.status' => $status,
                'OrganisationMember.approved' => 1
            ),
            'order' => $sort_order == 'alpha' ? array('Member.last_name' => 'asc') : array('OrganisationMember.id' => 'desc'), 
            'limit' => $limit,
            'offset' => $offset
        ));
        
        return $result;
    }
    
    /**
     * Returns the list of members who's name, email or mobile number matches
     * a specified search term and filters by the member status type, e.g.
     * member or visitor
     * 
     * @param int $organisation_id
     * @param int $term
     * @param string $status
     * @return array
     */
    public function findMembersBySearchTerm($organisation_id, $term, $organisation_member_category_id, $offset = 0, $limit = 50, $order = 'recent') {
        
        $conditions = array(
            'OrganisationMember.active' => 1,
            'OrganisationMember.organisation_id' => $organisation_id,
            'OrganisationMember.approved' => 1
        );
        
        // only check conditions if we have a non empty search term
        if( !empty($term) ) {
            $conditions['OR'] = array(
                'AND' => array(
                    "OrganisationMember.organisation_no LIKE" => "%$term%",
                    'NOT' => array(
                        'OrganisationMember.organisation_no' => '',
                        'OrganisationMember.organisation_no' => null
                    )
                ),
                "CONCAT(Member.first_name, ' ', Member.last_name) LIKE" => "%$term%",
                "CONCAT(Member.last_name, ' ', Member.first_name) LIKE" => "%$term%",
                'Member.email LIKE' => "%$term%",
                "REPLACE(REPLACE(Member.mobile_number, ' ', ''), '-','') LIKE" => "%" . str_replace("-", '', str_replace(" ", '', $term)) . "%"
            );
        }
        
        if( $organisation_member_category_id != -1 ) {
            $conditions['OrganisationMember.organisation_member_category_id'] = $organisation_member_category_id;
        }

        $members = $this->find('all', array(
            'contain' => array(
                'Member' => array(
                    'fields' => array('Member.id', 'Member.first_name', 'Member.last_name', 'Member.middle_name', 'Member.occupation'),
                    'MemberPhoneNumber' => array(
                        'conditions' => array('MemberPhoneNumber.type' => 'mobile'),
                        'limit' => 1
                    )
                )
            ),
            'fields' => array(
                'OrganisationMember.organisation_no', 'OrganisationMember.id'
            ),
            'conditions' => $conditions,
            'order' => $order == 'recent' ? array('OrganisationMember.created' => 'desc') : array('Member.last_name', 'Member.first_name'),
            'limit' => $limit,
            'offset' => $offset
        ));
        
        foreach($members as &$m) {
            if( isset($m['Member']['MemberPhoneNumber'][0]) ) {
                $m['Member']['mobile_number'] = $m['Member']['MemberPhoneNumber'][0]['number'];
                unset($m['Member']['MemberPhoneNumber']);
            }
        }

        return $members;
    }

    public function recentStatsByStatusType($organisation_id, $status, $interval = 1, $interval_type = 'MONTH') {
        $key = "rec_{$status}_{$organisation_id}";
        $result = Cache::read($key);
        
        if( !$result ) {
            $result = $this->find('all', array(
                'fields' => array("DATE_FORMAT(OrganisationMember.created, '%b %d') as dt", "COUNT(OrganisationMember.member_id) as count"),
                'conditions' => array(
                    'OrganisationMember.organisation_id' => $organisation_id,
                    'OrganisationMember.status' => $status,
                    'OrganisationMember.active' => 1,
                    'OrganisationMember.approved' => 1,
                    "OrganisationMember.created >= NOW() - INTERVAL $interval $interval_type"
                ),
                'group' => array('OrganisationMember.organisation_id', 'DATE(OrganisationMember.created)'),
                'order' => array('dt' => 'desc'),
                'limit' => 7,
                'recursive' => -1
            ));
            
            Cache::write($key, $result);
        }
        
        return $result;
    }
    
    public function approve($organisation_id, $member_id, $organisation_account_id) {
        $member = $this->find('first', array(
            'conditions' => array(
                'OrganisationMember.organisation_id' => $organisation_id,
                'OrganisationMember.member_id' => $member_id
            ),
            'recursive' => -1
        ));
        
        if( $member ) {
            $this->updateAll(array('approved' => 1, 'approved_by' => $organisation_account_id), 
                    array('OrganisationMember.organisation_id' => $organisation_id, 'OrganisationMember.member_id' => $member_id));

            $this->updateCounterCache(array(
                'organisation_id' => $organisation_id,
                'organisation_member_category_id' => $member['OrganisationMember']['organisation_member_category_id']
            ));
            
            return array('status' => 'success', 'message' => 'Member join request approved');
        }
        
        return array('status' => 'failed', 'message' => 'Member to update not found.');
    }
    
    public function decline($organisation_id, $member_id) {
        $member = $this->find('first', array(
            'conditions' => array(
                'OrganisationMember.organisation_id' => $organisation_id,
                'OrganisationMember.member_id' => $member_id
            ),
            'recursive' => -1
        ));
        
        if( $member ) {
            $this->updateAll(array('approved' => 0, 'approved_by' => null, 'active' => -1), 
                array('OrganisationMember.organisation_id' => $organisation_id, 'OrganisationMember.member_id' => $member_id));
            
            $this->updateCounterCache(array(
                'organisation_id' => $organisation_id,
                'organisation_member_category_id' => $member['OrganisationMember']['organisation_member_category_id']
            ));
            
            return array('status' => 'success', 'message' => 'Member join request declined successfully');
        }
        
        return array('status' => 'failed', 'message' => 'Member to update not found.');
    }
    
    public function upcomingBirthdays($organisation_id) {
        
        $members = $this->find('all', array(
            'contain' => array(
                'Member' => array(
                    'fields' => array('id', 'first_name', 'last_name', 'middle_name', 'dob', 'age', 'occupation'),
                    'MemberPhoneNumber' => array(
                        'conditions' => array('MemberPhoneNumber.type' => 'mobile')
                    )
                ),
                'OrganisationMemberImage' => array('MemberImage'),
                'OrganisationMemberCategory' => array(
                    'fields' => array('id', 'name')
                )
            ),
            'conditions' => array(
                'OrganisationMember.organisation_id' => $organisation_id,
                '(DATE_ADD(Member.dob, INTERVAL (YEAR(CURDATE()) - YEAR(Member.dob)) YEAR) 
                    BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 7 DAY)) '
            ),
            'limit' => 25,
            'order' => array('MONTH(Member.dob)', 'DAY(Member.dob)')
        ));
        
        return $members;
    }
    
    public function getStatsByCategory($organisation_id) {
        
        $data = $this->OrganisationMemberCategory->find('all', array(
            'conditions' => array('OrganisationMemberCategory.organisation_id' => $organisation_id),
            'recursive' => -1
        ));
        
        $stats = array();
        
        foreach($data as $d) {
            $stats[] = array(
                'category_id' => $d['OrganisationMemberCategory']['id'],
                'category_name' => $d['OrganisationMemberCategory']['name'],
                'members' => $d['OrganisationMemberCategory']['organisation_member_count'],
            );
        }
        
        return $stats;
    }
    
    /**
     * Change the membership category assigned to a member
     * 
     * @param type $organisation_id
     * @param type $category_id
     * @param type $member_id
     */
    public function changeCategory($organisation_id, $category_id, $member_id) {
        $member = $this->getAssociation($organisation_id, $member_id, false);
        
        if( !$member ) {
            return array('status' => 'failed', 'message' => 'Specified member does not belong to this organisation');
        }
        
        $category = $this->OrganisationMemberCategory->getCategory($organisation_id, $category_id);
        
        if( !$category ) {
            return array('status' => 'failed', 'message' => 'Specified membership category not found for this organisation');
        }
        
        $this->updateAll(array('OrganisationMember.organisation_member_category_id' => $category_id),
                array('OrganisationMember.organisation_id' => $organisation_id, 'OrganisationMember.member_id' => $member_id));
        
        if( isset($member['OrganisationMember']) ) {
            // keep the counters up to date
            $this->updateCounterCache(array(
                'organisation_member_category_id' => $member['OrganisationMember']['organisation_member_category_id']
            ));
        }
        
        // keep the counters up to date
        $this->updateCounterCache(array(
            'organisation_member_category_id' => $category_id
        ));
        
        return array('status' => 'success', 'message' => 'Membership category changed successfully');
    }
    
    public function saveAndUpdateProfile($data) {
        // ensure the membership source is set for future data records
        if( isset($data['OrganisationMember']['organisation_id']) ) {
            $data['Member']['source_organisation_id'] = $data['OrganisationMember']['organisation_id'];
        }
        
        $hasMany = array(
            'Member' => array(
                'MemberEmail' => 'email',
                'MemberPhoneNumber' => 'number',
                'MemberParent' => 'name',
                'MemberSpouse' => 'name',
                'MemberChild' => 'name'
            ),
            'OrganisationMemberGroup' => 'organisation_group_id',
            'OrganisationMemberAnniversary' => 'value',
            'OrganisationMemberImage' => 'member_image_id',
            'OrganisationMemberNote' => 'note'
        );

        // validate and remove empty model data so they are not saved
        foreach($hasMany as $parent => $models) {
            if( is_array($models) ) {
                foreach($models as $modelName => $field) {
                    if( isset($data[$parent][$modelName]) ) {
                        $tmp = array();

                        foreach($data[$parent][$modelName] as $model) {
                            if( isset($model[$field]) && $model[$field] != '' ) {
                                $tmp[] = $model;
                            }
                        }

                        if( $tmp ) {
                            $data[$parent][$modelName] = $tmp;
                        }

                        else {
                            unset($data[$parent][$modelName]);
                        }
                    }
                }
            }
            
            else {
                if( isset($data[$parent]) ) {
                    $tmp = array();

                    foreach($data[$parent] as $model) {
                        if( isset($model[$models]) && $model[$models] != '' ) {
                            $tmp[] = $model;
                        }
                    }

                    if( $tmp ) {
                        $data[$parent] = $tmp;
                    }

                    else {
                        unset($data[$parent]);
                    }
                }
            }
        }

        // save data for organisation member
        return $this->saveAll($data, array('atomic' => true, 'deep' => true));
            
    }
}
